package com.wd.maven.aggregation;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;


public class AggregationProjectGenerator {

    private static final Logger LOG = Logger.getInstance(AggregationProjectGenerator.class);

    public void generateProject(Project project, String groupId, String artifactId, String version, String[] modules, String javaVersion) {
        String baseDir = project.getBasePath();
        if ( baseDir == null || baseDir.isEmpty()) {
            LOG.warn("Project base directory not found.");
            return;
        }

        Path projectPath = Paths.get(baseDir);

        // 写入父 POM
        writeParentPom(projectPath, groupId, artifactId, version, modules, javaVersion);

        // 写入子模块
        for (String module : modules) {
            // 使用父项目名-子模块名的格式创建目录
            String moduleName = artifactId + "-" + module;
            Path modulePath = projectPath.resolve(moduleName);
            writeModulePom(modulePath, groupId, artifactId, version, moduleName);
            createDirectoryStructure(modulePath.resolve("src/main/java"));
            createDirectoryStructure(modulePath.resolve("src/test/java"));
            createDirectoryStructure(modulePath.resolve("src/main/resources"));
        }

        // 添加模块间依赖
        addModuleDependencies(projectPath, groupId, version, artifactId, modules);

        // README.md
        writeReadme(projectPath, artifactId, modules);

        // .gitignore
        writeGitignore(projectPath);
    }


    private void writeParentPom(Path projectPath, String groupId, String artifactId, String version, String[] modules, String javaVersion) {
        StringBuilder moduleXml = new StringBuilder();
        for (String module : modules) {
            // 使用父项目名-子模块名的格式
            String moduleName = artifactId + "-" + module;
            moduleXml.append("        <module>").append(moduleName).append("</module>\n");
        }

        StringBuilder dependencyManagementXml = new StringBuilder();
        for (String module : modules) {
            dependencyManagementXml.append("            <dependency>\n")
                    .append("                <groupId>").append(groupId).append("</groupId>\n")
                    .append("                <artifactId>").append(artifactId).append("-").append(module).append("</artifactId>\n") // 使用正确的 artifactId
                    .append("                <version>${project.version}</version>\n")
                    .append("            </dependency>\n");
        }

        String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n" +
                "         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
                "         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
                "    <modelVersion>4.0.0</modelVersion>\n" +
                "\n" +
                "    <groupId>" + groupId + "</groupId>\n" +
                "    <artifactId>" + artifactId + "</artifactId>\n" +
                "    <version>" + version + "</version>\n" +
                "    <packaging>pom</packaging>\n" +
                "\n" +
                "    <modules>\n" +
                moduleXml.toString() +
                "    </modules>\n" +
                "\n" +
                "    <properties>\n" +
                "        <maven.compiler.source>" + javaVersion + "</maven.compiler.source>\n" +
                "        <maven.compiler.target>" + javaVersion + "</maven.compiler.target>\n" +
                "        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n" +
                "    </properties>\n" +
                "\n" +
                "    <dependencyManagement>\n" +
                "        <dependencies>\n" +
                "            <!-- 项目内部模块依赖 -->\n" +
                dependencyManagementXml.toString() +
                "        </dependencies>\n" +
                "    </dependencyManagement>\n" +
                "</project>";

        writeToFile(projectPath.resolve("pom.xml"), content);
    }




    private void writeReadme(Path projectPath, String projectName, String[] modules) {
        StringBuilder modulesDescription = new StringBuilder();
        for (String module : modules) {
            modulesDescription.append("- `").append(module).append("`: ");

            // 根据模块名称添加描述
            if (module.equals("api")) {
                modulesDescription.append("对外暴露的API接口模块\n");
            } else if (module.equals("common")) {
                modulesDescription.append("公共工具类和通用组件模块\n");
            } else if (module.equals("mapper")) {
                modulesDescription.append("数据访问层模块\n");
            } else if (module.equals("pojo")) {
                modulesDescription.append("实体类模块\n");
            } else if (module.equals("service")) {
                modulesDescription.append("业务逻辑模块\n");
            } else {
                modulesDescription.append("自定义模块\n");
            }
        }

        String content = "# " + projectName + " Maven聚合项目\n\n" +
                "这是一个多模块Maven项目模板，通过模块化设计组织Java应用程序。\n\n" +
                "## 项目结构\n\n" +
                "```\n" +
                projectName + "/\n";

        // 添加模块目录结构
        for (String module : modules) {
            content += "├── " + module + "/\n";
        }

        content += "```\n\n" +
                "## 模块说明\n\n" +
                modulesDescription.toString() + "\n" +
                "## 开始使用\n\n" +
                "1. 根据需要修改各模块的`pom.xml`文件\n" +
                "2. 在相应模块中添加源代码\n" +
                "3. 使用以下命令构建项目：\n\n" +
                "```bash\n" +
                "mvn clean install\n" +
                "```\n";

        writeToFile(projectPath.resolve("README.md"), content);
    }

    private void writeGitignore(Path projectPath) {
        String content = "# Maven\n" +
                "target/\n" +
                "pom.xml.tag\n" +
                "pom.xml.releaseBackup\n" +
                "pom.xml.versionsBackup\n" +
                "pom.xml.next\n" +
                "release.properties\n" +
                "dependency-reduced-pom.xml\n" +
                "buildNumber.properties\n" +
                ".mvn/timing.properties\n" +
                ".mvn/wrapper/maven-wrapper.jar\n\n" +
                "# IntelliJ IDEA\n" +
                ".idea/\n" +
                "*.iws\n" +
                "*.iml\n" +
                "*.ipr\n\n" +
                "# Eclipse\n" +
                ".classpath\n" +
                ".project\n" +
                ".settings/\n\n" +
                "# Mac\n" +
                ".DS_Store\n";

        writeToFile(projectPath.resolve(".gitignore"), content);
    }
    private void writeModulePom(Path modulePath, String groupId, String parentArtifactId, String version, String projectName) {
        // 获取模块名称
        String moduleName = modulePath.getFileName().toString();

        // 新的 artifactId: 父项目名称-子模块名
        //String newArtifactId = parentArtifactId + "-" + moduleName;
        String newArtifactId =  moduleName;

        // 构建 pom.xml 内容
        String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n" +
                "         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
                "         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
                "    <modelVersion>4.0.0</modelVersion>\n" +
                "    <parent>\n" +
                "        <groupId>" + groupId + "</groupId>\n" +
                "        <artifactId>" + parentArtifactId + "</artifactId>\n" +
                "        <version>" + version + "</version>\n" +
                "    </parent>\n" +
                "    <artifactId>" + newArtifactId + "</artifactId>\n" + // 使用新的 artifactId
                "    <packaging>jar</packaging>\n" +
                "</project>";

        // 写入文件
        writeToFile(modulePath.resolve("pom.xml"), content);

        // 可选：手动验证 pom.xml 内容
        LOG.info("Generated pom.xml content for module " + moduleName + ":\n" + content);
    }

    private void addModuleDependencies(Path projectPath, String groupId, String version, String parentArtifactId, String[] modules) {
        LOG.info("开始添加模块间依赖关系...");
        LOG.info("项目路径: " + projectPath);
        LOG.info("父项目 artifactId: " + parentArtifactId);
        LOG.info("模块列表: " + Arrays.toString(modules));

        // 检查每个模块的 pom.xml 文件状态
        for (String module : modules) {
            Path modulePath = projectPath.resolve(parentArtifactId + "-" + module);
            Path pomPath = modulePath.resolve("pom.xml");
            LOG.info("Before adding dependencies, POM file existence for module " + module + ": " + Files.exists(pomPath));
        }

        // 默认依赖关系：api -> service -> mapper -> pojo -> common
        for (String module : modules) {
            // 使用父项目名-子模块名的格式创建目录，moduleName 也满足此格式
            String moduleName = parentArtifactId + "-" + module;

            LOG.info("处理模块: " + moduleName);

            if (module.equals("api") && containsModule(modules, "service")) {
                LOG.info("为模块 [api] 添加依赖: service");
                addDependencyToModule(projectPath.resolve(parentArtifactId + "-" + "api"), groupId, parentArtifactId, "service", version);
            } else if (module.equals("service") && containsModule(modules, "mapper")) {
                LOG.info("为模块 [service] 添加依赖: mapper");
                addDependencyToModule(projectPath.resolve(parentArtifactId + "-" + "service"), groupId, parentArtifactId, "mapper", version);
            } else if (module.equals("mapper") && containsModule(modules, "pojo")) {
                LOG.info("为模块 [mapper] 添加依赖: pojo");
                addDependencyToModule(projectPath.resolve(parentArtifactId + "-" + "mapper"), groupId, parentArtifactId, "pojo", version);
            } else if (module.equals("pojo") && containsModule(modules, "common")) {
                LOG.info("为模块 [pojo] 添加依赖: common");
                addDependencyToModule(projectPath.resolve(parentArtifactId + "-" + "pojo"), groupId, parentArtifactId, "common", version);
            } else {
                LOG.info("模块 [" + moduleName + "] 无需添加依赖");
            }
        }

        LOG.info("模块间依赖关系添加完成");
    }

    private void addDependencyToModule(Path modulePath, String groupId, String parentArtifactId, String moduleName, String version) {
        try {
            Path pomPath = modulePath.resolve("pom.xml");
            LOG.info("POM file path for module " + modulePath + ": " + pomPath);
            if (!Files.exists(pomPath)) {
                LOG.warn("POM file does not exist for module: " + modulePath);
                return;
            }

            String content = new String(Files.readAllBytes(pomPath));
            LOG.info("Original POM content for module " + modulePath + ":\n" + content);

            String dependencyXml = "    <dependency>\n" +
                    "        <groupId>" + groupId + "</groupId>\n" +
                    "        <artifactId>" + parentArtifactId + "-" + moduleName + "</artifactId>\n" +
                    "        <version>" + version + "</version>\n" +
                    "    </dependency>\n";

            if (content.contains("</dependencies>")) {
                // 已有依赖，在</dependencies>前添加
                int index = content.indexOf("</dependencies>");
                content = content.substring(0, index) + dependencyXml + content.substring(index);
            } else if (content.contains("</project>")) {
                // 没有依赖部分，在</project>前添加
                int index = content.indexOf("</project>");
                content = content.substring(0, index) + "    <dependencies>\n" + dependencyXml + "    </dependencies>\n" + content.substring(index);
            } else {
                LOG.warn("No suitable place to insert dependency in POM file for module: " + modulePath);
                return;
            }

            LOG.info("Updated POM content for module " + modulePath + ":\n" + content);
            Files.write(pomPath, content.getBytes());
        } catch (IOException e) {
            LOG.warn("Failed to add dependency to module: " + modulePath, e);
        }
    }






    private void writeToFile(Path path, String content) {
        try {
            // 创建父目录（如果不存在）
            Files.createDirectories(path.getParent());

            // 写入文件内容
            try (BufferedWriter writer = Files.newBufferedWriter(path)) {
                writer.write(content);
            }
        } catch (IOException e) {
            LOG.warn("Failed to write file: " + path, e);
        }
    }

    private void createDirectoryStructure(Path path) {
        try {
            Files.createDirectories(path);
        } catch (IOException e) {
            LOG.warn("Failed to create directory: " + path, e);
        }
    }





    private boolean containsModule(String[] modules, String moduleName) {
        for (String module : modules) {
            if (module.equals(moduleName)) {
                return true;
            }
        }
        return false;
    }



}